package com.ipan.poi.excel.log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ipan.poi.excel.WorkbookFactory;
import com.ipan.poi.excel.XlsObjectFactory;
import com.ipan.poi.excel.exporter.CellStyleCreatable;
import com.ipan.poi.excel.util.XlsUtils;
import com.ipan.poi.utils.PoiFileHelper;

/**
 * Excel失败记录工具类
 * 创建：简单工厂模式创建，不支持多线程并发；
 * 
 * @author iPan
 * @version 2013-09-15
 */
public final class XlsImportFailRecordLogger {
	private Logger logger = LoggerFactory.getLogger(getClass());
	/** 工作簿存放路径 */
	private String filePath = null;
	/** 工作簿 */
	private Workbook workbook = null;
	/** 当前操作的工作表 */
	private Sheet defaultSheet = null;
	/** 工作簿开关 true：打开，false：关闭 */
	private boolean open = false;
	/** 当前工作表的下标 */
	private int sheetIndex;
	/** 当前工作表的行号 */
	private int rowIndex;
	/** 文件输出流 */
	private FileOutputStream fout;
	// 默认样式
	private CellStyleCreatable cellStyleCreater = null;

	public static XlsImportFailRecordLogger createXlsFailRecordLogger(String filePath) {
		return new XlsImportFailRecordLogger(filePath);
	}
	
	public static XlsImportFailRecordLogger createXlsFailRecordLogger(String filePath, CellStyleCreatable cellStyleCreater) {
		return new XlsImportFailRecordLogger(filePath, cellStyleCreater);
	}

	private XlsImportFailRecordLogger(String filePath) {
		this.filePath = filePath;
		this.cellStyleCreater = XlsObjectFactory.createCellStyleCreater();
		resetSheetIndex();
		resetRowIndex();
	}
	
	private XlsImportFailRecordLogger(String filePath, CellStyleCreatable cellStyleCreater) {
		this.filePath = filePath;
		this.cellStyleCreater = cellStyleCreater;
		resetSheetIndex();
		resetRowIndex();
	}

	public void open() {
		if (!open) {
			File file = new File(filePath);
			if (!file.exists()) {
				PoiFileHelper.createFile(file.getAbsolutePath(), file.getAbsolutePath().length());
			}
			workbook = WorkbookFactory.createByFileExtension(file.getName());
			try {
				fout = new FileOutputStream(file);
			} catch (FileNotFoundException e) {
				throw new RuntimeException("创建" + filePath + "文件找不到！", e);
			}
			resetSheetIndex();
			resetRowIndex();
			open = true;
		}
	}

	public void close() {
		if (open) {
			try {
				fout.close();
				fout = null;
				open = false;
			} catch (Exception e) {
				logger.error("文件关闭异常！", e);
			}
		}
	}

	public boolean isOpen() {
		return open;
	}

	public String getFilePath() {
		return filePath;
	}

	public int getSheetIndex() {
		return sheetIndex;
	}

	public int getRowIndex() {
		return rowIndex;
	}
	
	public CellStyleCreatable getCellStyleCreater() {
		return cellStyleCreater;
	}

	public void setCellStyleCreater(CellStyleCreatable cellStyleCreater) {
		this.cellStyleCreater = cellStyleCreater;
	}

	public void write() {
		try {
			if (open) {
				workbook.write(fout);
			}
		} catch (IOException e) {
			throw new RuntimeException("写入Excel错误记录文件出错！", e);
		}
	}

	public Sheet createSheet(String name) {
		checkAndOpen();
		Sheet sheet = this.workbook.createSheet(name);
		this.defaultSheet = sheet;
		this.sheetIndex++;
		resetRowIndex();
		return sheet;
	}

	public Sheet getDefaultSheet() {
		return defaultSheet;
	}

	public void setDefaultSheet(Sheet defaultSheet, int index) {
		this.defaultSheet = defaultSheet;
		this.sheetIndex = index;
		resetRowIndex();
	}

	/**
	 * Excel写入Excel；
	 */
	public void addRow(Row fromRow) throws Exception {
		checkDefaultSheet();
		if (fromRow == null) {
			return;
		}
		Row toRow = this.defaultSheet.createRow(++this.rowIndex);
		XlsUtils.copyRow(fromRow, toRow);
	}
	/**
	 * 添加标题行
	 * 2016-04-13 新增
	 */
	public void addTitleRow(Row fromRow) throws Exception {
		checkDefaultSheet();
		if (fromRow == null) {
			return;
		}
		Row toRow = this.defaultSheet.createRow(++this.rowIndex);
		XlsUtils.copyRow2(fromRow, toRow, cellStyleCreater.createTitleStyle(workbook));
	}
	/**
	 * 添加正文行
	 * 2016-04-13 新增
	 */
	public void addBodyRow(Row fromRow) throws Exception {
		checkDefaultSheet();
		if (fromRow == null) {
			return;
		}
		Row toRow = this.defaultSheet.createRow(++this.rowIndex);
		XlsUtils.copyRow2(fromRow, toRow, cellStyleCreater.createBodyStyle(workbook));
	}
	
	private void checkDefaultSheet() {
		if (this.defaultSheet == null) {
			createSheet("sheet" + (this.getSheetIndex() + 1));
		}
	}
	
	private void checkAndOpen() {
		if (!isOpen()) {
			open();
		}
	}
	
	private void resetSheetIndex() {
		this.sheetIndex = -1;
	}
	
	private void resetRowIndex() {
		this.rowIndex = -1;
	}

}
